/*     */ package com.zimbra.cs.util;
/*     */ 
/*     */ import com.google.common.base.Charsets;
/*     */ import com.google.common.io.Closeables;
/*     */ import com.zimbra.common.account.Key.AccountBy;
/*     */ import com.zimbra.common.httpclient.HttpClientUtil;
/*     */ import com.zimbra.common.localconfig.KnownKey;
/*     */ import com.zimbra.common.localconfig.LC;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.soap.AdminConstants;
/*     */ import com.zimbra.common.soap.Element;
/*     */ import com.zimbra.common.soap.Element.Disposition;
/*     */ import com.zimbra.common.soap.Element.XMLElement;
/*     */ import com.zimbra.common.soap.MailConstants;
/*     */ import com.zimbra.common.soap.SoapFaultException;
/*     */ import com.zimbra.common.soap.SoapHttpTransport;
/*     */ import com.zimbra.common.util.BufferStream;
/*     */ import com.zimbra.common.util.ByteUtil;
/*     */ import com.zimbra.common.util.CliUtil;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.LogFactory;
/*     */ import com.zimbra.common.zmime.ZMimeMessage;
/*     */ import com.zimbra.common.zmime.ZSharedFileInputStream;
/*     */ import com.zimbra.cs.account.Account;
/*     */ import com.zimbra.cs.account.Config;
/*     */ import com.zimbra.cs.account.Provisioning;
/*     */ import com.zimbra.cs.account.Server;
/*     */ import com.zimbra.cs.mailbox.MailItem.Type;
/*     */ import com.zimbra.cs.mailbox.MailItem.UnderlyingData;
/*     */ import com.zimbra.cs.service.formatter.ArchiveFormatter.ArchiveInputEntry;
/*     */ import com.zimbra.cs.service.formatter.ArchiveFormatter.ArchiveInputStream;
/*     */ import com.zimbra.cs.service.formatter.TarArchiveInputStream;
/*     */ import com.zimbra.cs.service.util.ItemData;
/*     */ import java.io.BufferedOutputStream;
/*     */ import java.io.ByteArrayInputStream;
/*     */ import java.io.File;
/*     */ import java.io.FileOutputStream;
/*     */ import java.io.IOException;
/*     */ import java.io.InputStream;
/*     */ import java.io.OutputStream;
/*     */ import java.net.MalformedURLException;
/*     */ import java.net.URL;
/*     */ import java.nio.charset.Charset;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Iterator;
/*     */ import java.util.List;
/*     */ import java.util.Properties;
/*     */ import java.util.zip.GZIPInputStream;
/*     */ import javax.mail.BodyPart;
/*     */ import javax.mail.MessagingException;
/*     */ import javax.mail.Part;
/*     */ import javax.mail.Session;
/*     */ import javax.mail.internet.MimeMessage;
/*     */ import javax.mail.internet.MimeMultipart;
/*     */ import org.apache.commons.cli.CommandLine;
/*     */ import org.apache.commons.cli.CommandLineParser;
/*     */ import org.apache.commons.cli.GnuParser;
/*     */ import org.apache.commons.cli.HelpFormatter;
/*     */ import org.apache.commons.cli.Options;
/*     */ import org.apache.commons.cli.ParseException;
/*     */ import org.apache.commons.httpclient.Cookie;
/*     */ import org.apache.commons.httpclient.HostConfiguration;
/*     */ import org.apache.commons.httpclient.HttpClient;
/*     */ import org.apache.commons.httpclient.HttpException;
/*     */ import org.apache.commons.httpclient.HttpState;
/*     */ import org.apache.commons.httpclient.methods.GetMethod;
/*     */ import org.apache.commons.httpclient.params.HttpMethodParams;
/*     */ import org.apache.commons.httpclient.protocol.Protocol;
/*     */ import org.apache.commons.lang.StringUtils;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class SpamExtract
/*     */ {
/*  91 */   private static Log LOG = LogFactory.getLog(SpamExtract.class);
/*     */   
/*  93 */   private static Options options = new Options();
/*     */   
/*  95 */   private static boolean verbose = false;
/*     */   
/*  97 */   private static int BATCH_SIZE = 25;
/*     */   
/*  99 */   private static int SLEEP_TIME = 100;
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private static Session mJMSession;
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private static void usage(String errmsg)
/*     */   {
/* 122 */     if (errmsg != null) {
/* 123 */       LOG.error(errmsg);
/*     */     }
/* 125 */     HelpFormatter formatter = new HelpFormatter();
/* 126 */     formatter.printHelp("zmspamextract [options] ", "where [options] are one of:", options, "SpamExtract retrieve messages that may have been marked as spam or not spam in the Zimbra Web Client.");
/*     */     
/*     */ 
/* 129 */     System.exit(errmsg == null ? 0 : 1);
/*     */   }
/*     */   
/*     */   private static CommandLine parseArgs(String[] args) {
/* 133 */     CommandLineParser parser = new GnuParser();
/* 134 */     CommandLine cl = null;
/*     */     try {
/* 136 */       cl = parser.parse(options, args);
/*     */     } catch (ParseException pe) {
/* 138 */       usage(pe.getMessage());
/*     */     }
/*     */     
/* 141 */     if (cl.hasOption("h")) {
/* 142 */       usage(null);
/*     */     }
/* 144 */     return cl;
/*     */   }
/*     */   
/*     */   public static void main(String[] args) throws ServiceException, HttpException, SoapFaultException, IOException {
/* 148 */     CommandLine cl = parseArgs(args);
/*     */     
/* 150 */     if (cl.hasOption('D')) {
/* 151 */       CliUtil.toolSetup("DEBUG");
/*     */     } else {
/* 153 */       CliUtil.toolSetup("INFO");
/*     */     }
/* 155 */     if (cl.hasOption('v')) {
/* 156 */       verbose = true;
/*     */     }
/*     */     
/* 159 */     boolean optDelete = cl.hasOption('d');
/*     */     
/* 161 */     if (!cl.hasOption('o')) {
/* 162 */       usage("must specify directory to extract messages to");
/*     */     }
/* 164 */     String optDirectory = cl.getOptionValue('o');
/* 165 */     File outputDirectory = new File(optDirectory);
/* 166 */     if (!outputDirectory.exists()) {
/* 167 */       LOG.info("Creating directory: " + optDirectory);
/* 168 */       outputDirectory.mkdirs();
/* 169 */       if (!outputDirectory.exists()) {
/* 170 */         LOG.error("could not create directory " + optDirectory);
/* 171 */         System.exit(2);
/*     */       }
/*     */     }
/*     */     String optAdminUser;
/*     */     String optAdminUser;
/* 176 */     if (cl.hasOption('a')) {
/* 177 */       optAdminUser = cl.getOptionValue('a');
/*     */     } else {
/* 179 */       optAdminUser = LC.zimbra_ldap_user.value();
/*     */     }
/*     */     String optAdminPassword;
/*     */     String optAdminPassword;
/* 183 */     if (cl.hasOption('p')) {
/* 184 */       optAdminPassword = cl.getOptionValue('p');
/*     */     } else {
/* 186 */       optAdminPassword = LC.zimbra_ldap_password.value();
/*     */     }
/*     */     
/* 189 */     String optQuery = "in:inbox";
/* 190 */     if (cl.hasOption('q')) {
/* 191 */       optQuery = cl.getOptionValue('q');
/*     */     }
/*     */     
/* 194 */     Account account = getAccount(cl);
/* 195 */     if (account == null) {
/* 196 */       System.exit(1);
/*     */     }
/*     */     
/* 199 */     boolean optRaw = cl.hasOption('r');
/*     */     
/* 201 */     if (verbose) {
/* 202 */       LOG.info("Extracting from account " + account.getName());
/*     */     }
/*     */     
/* 205 */     Server server = Provisioning.getInstance().getServer(account);
/*     */     String optAdminURL;
/*     */     String optAdminURL;
/* 208 */     if (cl.hasOption('u')) {
/* 209 */       optAdminURL = cl.getOptionValue('u');
/*     */     } else {
/* 211 */       optAdminURL = getSoapURL(server, true);
/*     */     }
/* 213 */     String adminAuthToken = getAdminAuthToken(optAdminURL, optAdminUser, optAdminPassword);
/* 214 */     String authToken = getDelegateAuthToken(optAdminURL, account, adminAuthToken);
/* 215 */     BATCH_SIZE = Provisioning.getInstance().getLocalServer().getAntispamExtractionBatchSize();
/* 216 */     SLEEP_TIME = Provisioning.getInstance().getLocalServer().getAntispamExtractionBatchDelay();
/* 217 */     extract(authToken, account, server, optQuery, outputDirectory, optDelete, optRaw);
/*     */   }
/*     */   
/*     */   private static void extract(String authToken, Account account, Server server, String query, File outdir, boolean delete, boolean raw) throws ServiceException, HttpException, SoapFaultException, IOException {
/* 221 */     String soapURL = getSoapURL(server, false);
/*     */     
/* 223 */     URL restURL = getServerURL(server, false);
/* 224 */     HttpClient hc = new HttpClient();
/* 225 */     HttpState state = new HttpState();
/* 226 */     GetMethod gm = new GetMethod();
/* 227 */     gm.setFollowRedirects(true);
/* 228 */     Cookie authCookie = new Cookie(restURL.getHost(), "ZM_AUTH_TOKEN", authToken, "/", -1, false);
/* 229 */     state.addCookie(authCookie);
/* 230 */     hc.setState(state);
/* 231 */     hc.getHostConfiguration().setHost(restURL.getHost(), restURL.getPort(), Protocol.getProtocol(restURL.getProtocol()));
/* 232 */     gm.getParams().setSoTimeout(60000);
/*     */     
/* 234 */     if (verbose) {
/* 235 */       LOG.info("Mailbox requests to: " + restURL);
/*     */     }
/*     */     
/* 238 */     SoapHttpTransport transport = new SoapHttpTransport(soapURL);
/* 239 */     transport.setRetryCount(1);
/* 240 */     transport.setTimeout(0);
/* 241 */     transport.setAuthToken(authToken);
/*     */     
/* 243 */     int totalProcessed = 0;
/* 244 */     boolean haveMore = true;
/* 245 */     int offset = 0;
/* 246 */     while (haveMore) {
/* 247 */       Element searchReq = new Element.XMLElement(MailConstants.SEARCH_REQUEST);
/* 248 */       searchReq.addElement("query").setText(query);
/* 249 */       searchReq.addAttribute("types", MailItem.Type.MESSAGE.toString());
/* 250 */       searchReq.addAttribute("offset", offset);
/* 251 */       searchReq.addAttribute("limit", BATCH_SIZE);
/*     */       try
/*     */       {
/* 254 */         if (LOG.isDebugEnabled()) {
/* 255 */           LOG.debug(searchReq.prettyPrint());
/*     */         }
/* 257 */         Element searchResp = transport.invoke(searchReq, false, true, account.getId());
/* 258 */         if (LOG.isDebugEnabled()) {
/* 259 */           LOG.debug(searchResp.prettyPrint());
/*     */         }
/*     */         
/* 262 */         StringBuilder deleteList = new StringBuilder();
/*     */         
/* 264 */         List<String> ids = new ArrayList();
/* 265 */         for (Iterator<Element> iter = searchResp.elementIterator("m"); iter.hasNext();) {
/* 266 */           offset++;
/* 267 */           Element e = (Element)iter.next();
/* 268 */           String mid = e.getAttribute("id");
/* 269 */           if (mid == null) {
/* 270 */             LOG.warn("null message id SOAP response");
/*     */           }
/*     */           else
/*     */           {
/* 274 */             LOG.debug("adding id %s", new Object[] { mid });
/* 275 */             ids.add(mid);
/* 276 */             if ((ids.size() >= BATCH_SIZE) || (!iter.hasNext())) {
/* 277 */               StringBuilder path = new StringBuilder("/service/user/" + account.getName() + "/?fmt=tgz&list=" + StringUtils.join(ids, ","));
/* 278 */               LOG.debug("sending request for path %s", new Object[] { path.toString() });
/* 279 */               List<String> extractedIds = extractMessages(hc, gm, path.toString(), outdir, raw);
/* 280 */               if (ids.size() > extractedIds.size()) {
/* 281 */                 ids.removeAll(extractedIds);
/* 282 */                 LOG.warn("failed to extract %s", new Object[] { ids });
/*     */               }
/* 284 */               for (String id : extractedIds) {
/* 285 */                 deleteList.append(id).append(',');
/*     */               }
/*     */               
/* 288 */               ids.clear();
/*     */             }
/* 290 */             totalProcessed++;
/*     */           }
/*     */         }
/* 293 */         haveMore = false;
/* 294 */         String more = searchResp.getAttribute("more");
/* 295 */         if ((more != null) && (more.length() > 0)) {
/*     */           try {
/* 297 */             int m = Integer.parseInt(more);
/* 298 */             if (m > 0) {
/* 299 */               haveMore = true;
/*     */               try {
/* 301 */                 Thread.sleep(SLEEP_TIME);
/*     */               }
/*     */               catch (InterruptedException e) {}
/*     */             }
/*     */           } catch (NumberFormatException nfe) {
/* 306 */             LOG.warn("more flag from server not a number: " + more, nfe);
/*     */           }
/*     */         }
/*     */         
/* 310 */         if ((delete) && (deleteList.length() > 0)) {
/* 311 */           deleteList.deleteCharAt(deleteList.length() - 1);
/* 312 */           Element msgActionReq = new Element.XMLElement(MailConstants.MSG_ACTION_REQUEST);
/* 313 */           Element action = msgActionReq.addElement("action");
/* 314 */           action.addAttribute("id", deleteList.toString());
/* 315 */           action.addAttribute("op", "delete");
/*     */           
/* 317 */           if (LOG.isDebugEnabled()) {
/* 318 */             LOG.debug(msgActionReq.prettyPrint());
/*     */           }
/* 320 */           Element msgActionResp = transport.invoke(msgActionReq, false, true, account.getId());
/* 321 */           if (LOG.isDebugEnabled()) {
/* 322 */             LOG.debug(msgActionResp.prettyPrint());
/*     */           }
/* 324 */           offset = 0;
/*     */         }
/*     */       } finally {
/* 327 */         gm.releaseConnection();
/*     */       }
/*     */     }
/*     */     
/* 331 */     LOG.info("Total messages processed: " + totalProcessed);
/*     */   }
/*     */   
/*     */   static
/*     */   {
/* 102 */     options.addOption("s", "spam", false, "extract messages from configured spam mailbox");
/* 103 */     options.addOption("n", "notspam", false, "extract messages from configured notspam mailbox");
/* 104 */     options.addOption("m", "mailbox", true, "extract messages from specified mailbox");
/*     */     
/* 106 */     options.addOption("d", "delete", false, "delete extracted messages (default is to keep)");
/* 107 */     options.addOption("o", "outdir", true, "directory to store extracted messages");
/*     */     
/* 109 */     options.addOption("a", "admin", true, "admin user name for auth (default is zimbra_ldap_userdn)");
/* 110 */     options.addOption("p", "password", true, "admin password for auth (default is zimbra_ldap_password)");
/* 111 */     options.addOption("u", "url", true, "admin SOAP service url (default is target mailbox's server's admin service port)");
/*     */     
/* 113 */     options.addOption("q", "query", true, "search query whose results should be extracted (default is in:inbox)");
/* 114 */     options.addOption("r", "raw", false, "extract raw message (default: gets message/rfc822 attachments)");
/*     */     
/* 116 */     options.addOption("h", "help", false, "show this usage text");
/* 117 */     options.addOption("D", "debug", false, "enable debug level logging");
/* 118 */     options.addOption("v", "verbose", false, "be verbose while running");
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 339 */     Properties props = new Properties();
/* 340 */     props.setProperty("mail.mime.address.strict", "false");
/* 341 */     mJMSession = Session.getInstance(props); }
/* 342 */   private static String mOutputPrefix = Long.toHexString(System.currentTimeMillis());
/*     */   private static int mExtractIndex;
/*     */   private static final int MAX_BUFFER_SIZE = 10485760;
/*     */   
/*     */   private static List<String> extractMessages(HttpClient hc, GetMethod gm, String path, File outdir, boolean raw)
/*     */     throws HttpException, IOException
/*     */   {
/* 349 */     List<String> extractedIds = new ArrayList();
/* 350 */     gm.setPath(path);
/* 351 */     if (LOG.isDebugEnabled()) {
/* 352 */       LOG.debug("Fetching " + path);
/*     */     }
/* 354 */     HttpClientUtil.executeMethod(hc, gm);
/* 355 */     if (gm.getStatusCode() != 200) {
/* 356 */       throw new IOException("HTTP GET failed: " + gm.getPath() + ": " + gm.getStatusCode() + ": " + gm.getStatusText());
/*     */     }
/*     */     
/* 359 */     ArchiveFormatter.ArchiveInputStream tgzStream = null;
/*     */     try {
/* 361 */       tgzStream = new TarArchiveInputStream(new GZIPInputStream(gm.getResponseBodyAsStream()), Charsets.UTF_8.name());
/* 362 */       ArchiveFormatter.ArchiveInputEntry entry = null;
/* 363 */       while ((entry = tgzStream.getNextEntry()) != null) {
/* 364 */         LOG.debug("got entry name %s", new Object[] { entry.getName() });
/* 365 */         if (entry.getName().endsWith(".meta")) {
/* 366 */           ItemData itemData = new ItemData(readArchiveEntry(tgzStream, entry));
/* 367 */           MailItem.UnderlyingData ud = itemData.ud;
/* 368 */           entry = tgzStream.getNextEntry();
/* 369 */           if (raw)
/*     */           {
/* 371 */             File file = new File(outdir, mOutputPrefix + "-" + mExtractIndex++);
/* 372 */             OutputStream os = null;
/*     */             try {
/* 374 */               os = new BufferedOutputStream(new FileOutputStream(file));
/* 375 */               byte[] data = readArchiveEntry(tgzStream, entry);
/* 376 */               ByteUtil.copy(new ByteArrayInputStream(data), true, os, false);
/* 377 */               if (verbose) {
/* 378 */                 LOG.info("Wrote: " + file);
/*     */               }
/* 380 */               extractedIds.add(ud.id + "");
/*     */             } catch (IOException e) {
/* 382 */               String fileName = outdir + "/" + mOutputPrefix + "-" + mExtractIndex;
/* 383 */               LOG.error("Cannot write to " + fileName, e);
/*     */             } finally {
/* 385 */               if (os != null) {
/* 386 */                 os.close();
/*     */               }
/*     */             }
/*     */           }
/*     */           else {
/* 391 */             BufferStream buffer = new BufferStream(entry.getSize(), 10485760);
/* 392 */             buffer.setSequenced(false);
/* 393 */             MimeMessage mm = null;
/* 394 */             InputStream fis = null;
/*     */             try {
/* 396 */               byte[] data = readArchiveEntry(tgzStream, entry);
/* 397 */               ByteUtil.copy(new ByteArrayInputStream(data), true, buffer, false);
/* 398 */               if (buffer.isSpooled()) {
/* 399 */                 fis = new ZSharedFileInputStream(buffer.getFile());
/* 400 */                 mm = new ZMimeMessage(mJMSession, fis);
/*     */               } else {
/* 402 */                 mm = new ZMimeMessage(mJMSession, buffer.getInputStream());
/*     */               }
/* 404 */               writeAttachedMessages(mm, outdir, entry.getName());
/* 405 */               extractedIds.add(ud.id + "");
/*     */             } catch (MessagingException me) {
/* 407 */               LOG.warn("exception occurred fetching message", me);
/*     */             }
/*     */             finally {}
/*     */           }
/*     */         }
/*     */       }
/*     */     }
/*     */     finally
/*     */     {
/* 416 */       Closeables.closeQuietly(tgzStream);
/*     */     }
/* 418 */     return extractedIds;
/*     */   }
/*     */   
/*     */   private static byte[] readArchiveEntry(ArchiveFormatter.ArchiveInputStream ais, ArchiveFormatter.ArchiveInputEntry aie) throws IOException
/*     */   {
/* 423 */     if (aie == null) {
/* 424 */       return null;
/*     */     }
/*     */     
/* 427 */     int dsz = (int)aie.getSize();
/*     */     
/*     */ 
/* 430 */     if (dsz == 0)
/* 431 */       return null;
/* 432 */     byte[] data; byte[] data; if (dsz == -1) {
/* 433 */       data = ByteUtil.getContent(ais.getInputStream(), -1, false);
/*     */     } else {
/* 435 */       data = new byte[dsz];
/* 436 */       if (ais.read(data, 0, dsz) != dsz) {
/* 437 */         throw new IOException("archive read err");
/*     */       }
/*     */     }
/* 440 */     return data;
/*     */   }
/*     */   
/*     */   private static void writeAttachedMessages(MimeMessage mm, File outdir, String msgUri)
/*     */     throws IOException, MessagingException
/*     */   {
/* 446 */     if (!(mm.getContent() instanceof MimeMultipart)) {
/* 447 */       LOG.warn("Spam/notspam messages must have attachments (skipping " + msgUri + ")");
/* 448 */       return;
/*     */     }
/*     */     
/* 451 */     MimeMultipart mmp = (MimeMultipart)mm.getContent();
/* 452 */     int nAttachments = mmp.getCount();
/* 453 */     boolean foundAtleastOneAttachedMessage = false;
/* 454 */     for (int i = 0; i < nAttachments; i++) {
/* 455 */       BodyPart bp = mmp.getBodyPart(i);
/* 456 */       if (bp.isMimeType("message/rfc822"))
/*     */       {
/*     */ 
/*     */ 
/* 460 */         foundAtleastOneAttachedMessage = true;
/* 461 */         Part msg = (Part)bp.getContent();
/* 462 */         File file = new File(outdir, mOutputPrefix + "-" + mExtractIndex++);
/* 463 */         OutputStream os = null;
/*     */         try {
/* 465 */           os = new BufferedOutputStream(new FileOutputStream(file));
/* 466 */           if ((msg instanceof MimeMessage))
/*     */           {
/* 468 */             ZMimeMessage newMsg = new ZMimeMessage((MimeMessage)msg);
/* 469 */             newMsg.writeTo(os);
/*     */           } else {
/* 471 */             msg.writeTo(os);
/*     */           }
/*     */         } finally {
/* 474 */           os.close();
/*     */         }
/* 476 */         if (verbose) LOG.info("Wrote: " + file);
/*     */       }
/*     */     }
/* 479 */     if (!foundAtleastOneAttachedMessage) {
/* 480 */       String msgid = mm.getHeader("Message-ID", " ");
/* 481 */       LOG.warn("message uri=" + msgUri + " message-id=" + msgid + " had no attachments");
/*     */     }
/*     */   }
/*     */   
/*     */   public static URL getServerURL(Server server, boolean admin) throws ServiceException {
/* 486 */     String host = server.getAttr("zimbraServiceHostname");
/* 487 */     if (host == null) {
/* 488 */       throw ServiceException.FAILURE("invalid zimbraServiceHostname in server " + server.getName(), null);
/*     */     }
/*     */     
/* 491 */     String protocol = "http";
/* 492 */     String portAttr = "zimbraMailPort";
/*     */     
/* 494 */     if (admin) {
/* 495 */       protocol = "https";
/* 496 */       portAttr = "zimbraAdminPort";
/*     */     } else {
/* 498 */       String mode = server.getAttr("zimbraMailMode");
/* 499 */       if (mode == null) {
/* 500 */         throw ServiceException.FAILURE("null zimbraMailMode in server " + server.getName(), null);
/*     */       }
/* 502 */       if (mode.equalsIgnoreCase("https")) {
/* 503 */         protocol = "https";
/* 504 */         portAttr = "zimbraMailSSLPort";
/*     */       }
/* 506 */       if (mode.equalsIgnoreCase("redirect")) {
/* 507 */         protocol = "https";
/* 508 */         portAttr = "zimbraMailSSLPort";
/*     */       }
/*     */     }
/*     */     
/* 512 */     int port = server.getIntAttr(portAttr, -1);
/* 513 */     if (port < 1) {
/* 514 */       throw ServiceException.FAILURE("invalid " + portAttr + " in server " + server.getName(), null);
/*     */     }
/*     */     try
/*     */     {
/* 518 */       return new URL(protocol, host, port, "");
/*     */     } catch (MalformedURLException mue) {
/* 520 */       throw ServiceException.FAILURE("exception creating url (protocol=" + protocol + " host=" + host + " port=" + port + ")", mue);
/*     */     }
/*     */   }
/*     */   
/*     */   public static String getSoapURL(Server server, boolean admin) throws ServiceException {
/* 525 */     String url = getServerURL(server, admin).toString();
/* 526 */     String file = admin ? "/service/admin/soap/" : "/service/soap/";
/* 527 */     return url + file;
/*     */   }
/*     */   
/*     */   public static String getAdminAuthToken(String adminURL, String adminUser, String adminPassword) throws ServiceException {
/* 531 */     SoapHttpTransport transport = new SoapHttpTransport(adminURL);
/* 532 */     transport.setRetryCount(1);
/* 533 */     transport.setTimeout(0);
/*     */     
/* 535 */     Element authReq = new Element.XMLElement(AdminConstants.AUTH_REQUEST);
/* 536 */     authReq.addAttribute("name", adminUser, Element.Disposition.CONTENT);
/* 537 */     authReq.addAttribute("password", adminPassword, Element.Disposition.CONTENT);
/*     */     try {
/* 539 */       if (verbose) LOG.info("Auth request to: " + adminURL);
/* 540 */       if (LOG.isDebugEnabled()) LOG.debug(authReq.prettyPrint());
/* 541 */       Element authResp = transport.invokeWithoutSession(authReq);
/* 542 */       if (LOG.isDebugEnabled()) LOG.debug(authResp.prettyPrint());
/* 543 */       return authResp.getAttribute("authToken");
/*     */     }
/*     */     catch (Exception e) {
/* 546 */       throw ServiceException.FAILURE("admin auth failed url=" + adminURL, e);
/*     */     }
/*     */   }
/*     */   
/*     */   public static String getDelegateAuthToken(String adminURL, Account account, String adminAuthToken) throws ServiceException {
/* 551 */     SoapHttpTransport transport = new SoapHttpTransport(adminURL);
/* 552 */     transport.setRetryCount(1);
/* 553 */     transport.setTimeout(0);
/* 554 */     transport.setAuthToken(adminAuthToken);
/*     */     
/* 556 */     Element daReq = new Element.XMLElement(AdminConstants.DELEGATE_AUTH_REQUEST);
/* 557 */     Element acctElem = daReq.addElement("account");
/* 558 */     acctElem.addAttribute("by", "id");
/* 559 */     acctElem.setText(account.getId());
/*     */     try {
/* 561 */       if (verbose) LOG.info("Delegate auth request to: " + adminURL);
/* 562 */       if (LOG.isDebugEnabled()) LOG.debug(daReq.prettyPrint());
/* 563 */       Element daResp = transport.invokeWithoutSession(daReq);
/* 564 */       if (LOG.isDebugEnabled()) LOG.debug(daResp.prettyPrint());
/* 565 */       return daResp.getAttribute("authToken");
/*     */     }
/*     */     catch (Exception e) {
/* 568 */       throw ServiceException.FAILURE("Delegate auth failed url=" + adminURL, e);
/*     */     }
/*     */   }
/*     */   
/*     */   private static Account getAccount(CommandLine cl) throws ServiceException {
/* 573 */     Provisioning prov = Provisioning.getInstance();
/*     */     Config conf;
/*     */     try {
/* 576 */       conf = prov.getConfig();
/*     */     } catch (ServiceException e) {
/* 578 */       throw ServiceException.FAILURE("Unable to connect to LDAP directory", e);
/*     */     }
/*     */     
/* 581 */     String name = null;
/*     */     
/* 583 */     if (cl.hasOption('s')) {
/* 584 */       if ((cl.hasOption('n')) || (cl.hasOption('m'))) {
/* 585 */         LOG.error("only one of s, n or m options can be specified");
/* 586 */         return null;
/*     */       }
/* 588 */       name = conf.getAttr("zimbraSpamIsSpamAccount");
/* 589 */       if ((name == null) || (name.length() == 0)) {
/* 590 */         LOG.error("no account configured for spam");
/* 591 */         return null;
/*     */       }
/* 593 */     } else if (cl.hasOption('n')) {
/* 594 */       if (cl.hasOption('m')) {
/* 595 */         LOG.error("only one of s, n, or m options can be specified");
/* 596 */         return null;
/*     */       }
/* 598 */       name = conf.getAttr("zimbraSpamIsNotSpamAccount");
/* 599 */       if ((name == null) || (name.length() == 0)) {
/* 600 */         LOG.error("no account configured for ham");
/* 601 */         return null;
/*     */       }
/* 603 */     } else if (cl.hasOption('m')) {
/* 604 */       name = cl.getOptionValue('m');
/* 605 */       if (name.length() == 0) {
/* 606 */         LOG.error("illegal argument to m option");
/* 607 */         return null;
/*     */       }
/*     */     } else {
/* 610 */       LOG.error("one of s, n or m options must be specified");
/* 611 */       return null;
/*     */     }
/*     */     
/* 614 */     Account account = prov.get(Key.AccountBy.name, name);
/* 615 */     if (account == null) {
/* 616 */       LOG.error("can not find account " + name);
/* 617 */       return null;
/*     */     }
/*     */     
/* 620 */     return account;
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/util/SpamExtract.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */